/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "sample_pufs.h"

struct bc_test_pattern {
    uint8_t cipher;
    uint32_t keybits;
    const void* key;
    uint32_t ptlen;
    const void* pt;
    uint32_t ivlen;
    const void* iv;
    uint32_t ctlen;
    const void* ct;
};

static const struct bc_test_pattern aes_ecb_tp[] = {
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        0, NULL,
        64, "\x3a\xd7\x7b\xb4\x0d\x7a\x36\x60\xa8\x9e\xca\xf3\x24\x66\xef\x97\xf5\xd3\xd5\x85\x03\xb9\x69\x9d\xe7\x85\x89\x5a\x96\xfd\xba\xaf\x43\xb1\xcd\x7f\x59\x8e\xce\x23\x88\x1b\x00\xe3\xed\x03\x06\x88\x7b\x0c\x78\x5e\x27\xe8\xad\x3f\x82\x23\x20\x71\x04\x72\x5d\xd4" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        0, NULL,
        64, "\xbd\x33\x4f\x1d\x6e\x45\xf2\x5f\xf7\x12\xa2\x14\x57\x1f\xa5\xcc\x97\x41\x04\x84\x6d\x0a\xd3\xad\x77\x34\xec\xb3\xec\xee\x4e\xef\xef\x7a\xfd\x22\x70\xe2\xe6\x0a\xdc\xe0\xba\x2f\xac\xe6\x44\x4e\x9a\x4b\x41\xba\x73\x8d\x6c\x72\xfb\x16\x69\x16\x03\xc1\x8e\x0e" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        0, NULL,
        64, "\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\x06\x4b\x5a\x7e\x3d\xb1\x81\xf8\x59\x1c\xcb\x10\xd4\x10\xed\x26\xdc\x5b\xa7\x4a\x31\x36\x28\x70\xb6\xed\x21\xb9\x9c\xa6\xf4\xf9\xf1\x53\xe7\xb1\xbe\xaf\xed\x1d\x23\x30\x4b\x7a\x39\xf9\xf3\xff\x06\x7d\x8d\x8f\x9e\x24\xec\xc7" },
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        0, NULL,
        69, "\x3a\xd7\x7b\xb4\x0d\x7a\x36\x60\xa8\x9e\xca\xf3\x24\x66\xef\x97\xf5\xd3\xd5\x85\x03\xb9\x69\x9d\xe7\x85\x89\x5a\x96\xfd\xba\xaf\x43\xb1\xcd\x7f\x59\x8e\xce\x23\x88\x1b\x00\xe3\xed\x03\x06\x88\x7b\x0c\x78\x5e\x27\xe8\xad\x3f\x82\x23\x20\x71\x04\x72\x5d\xd4ggggg" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        0, NULL,
        69, "\xbd\x33\x4f\x1d\x6e\x45\xf2\x5f\xf7\x12\xa2\x14\x57\x1f\xa5\xcc\x97\x41\x04\x84\x6d\x0a\xd3\xad\x77\x34\xec\xb3\xec\xee\x4e\xef\xef\x7a\xfd\x22\x70\xe2\xe6\x0a\xdc\xe0\xba\x2f\xac\xe6\x44\x4e\x9a\x4b\x41\xba\x73\x8d\x6c\x72\xfb\x16\x69\x16\x03\xc1\x8e\x0eggggg" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        0, NULL,
        69, "\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\x06\x4b\x5a\x7e\x3d\xb1\x81\xf8\x59\x1c\xcb\x10\xd4\x10\xed\x26\xdc\x5b\xa7\x4a\x31\x36\x28\x70\xb6\xed\x21\xb9\x9c\xa6\xf4\xf9\xf1\x53\xe7\xb1\xbe\xaf\xed\x1d\x23\x30\x4b\x7a\x39\xf9\xf3\xff\x06\x7d\x8d\x8f\x9e\x24\xec\xc7ggggg" },
};

static const struct bc_test_pattern aes_cfb_tp[] = {
    {
        SK_AES,
        128,
        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6",
    },
    {
        SK_AES,
        192,
        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff",
    },
    {
        SK_AES,
        256,
        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71",
    },
    {
        SK_AES,
        128,
        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        69,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69,
        "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6ggggg",
    },
    {
        SK_AES,
        192,
        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        69,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69,
        "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xffggggg",
    },
    {
        SK_AES,
        256,
        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        69,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69,
        "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71ggggg",
    },
};

static const struct bc_test_pattern aes_ofb_tp[] = {
    {
        SK_AES,
        128,
        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e",
    },
    {
        SK_AES,
        192,
        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a",
    },
    {
        SK_AES,
        256,
        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        64,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84",
    },
    {
        SK_AES,
        128,
        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        59,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        59,
        "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10",
    },
    {
        SK_AES,
        192,
        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        59,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        59,
        "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52",
    },
    {
        SK_AES,
        256,
        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        59,
        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        59,
        "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a",
    },
};

static const struct bc_test_pattern aes_cbc_tp[] = {
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64, "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2\x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16\x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64, "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8\xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a\x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0\x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcd" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64, "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d\x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1b" },
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69, "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2\x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16\x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7ggggg" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69, "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8\xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a\x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0\x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcdggggg" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        69, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10ggggg",
        16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        69, "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d\x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1bggggg" },
};

static const struct bc_test_pattern aes_cbc_cs1_tp[] = {
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 31, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 31, "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" },
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 32, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" },
};

static const struct bc_test_pattern aes_cbc_cs2_tp[] = {
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 31, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 31, "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5" },
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 32, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" },
};

static const struct bc_test_pattern aes_cbc_cs3_tp[] = {
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 31, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 31, "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5" },
    { SK_AES, 128, "\x63\x68\x69\x63\x6b\x65\x6e\x20\x74\x65\x72\x69\x79\x61\x6b\x69", 32, "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43", 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" },
};

static const struct bc_test_pattern aes_ctr_tp[] = {
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        64, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        64, "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        64, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        64, "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" },
    { SK_AES,
        128, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
        59, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        59, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70" },
    { SK_AES,
        192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
        59, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        59, "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda" },
    { SK_AES,
        256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
        59, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41",
        16, "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
        59, "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd" },
};

static const struct bc_test_pattern sm4_ecb_tp[] = {
    {
        SK_SM4,
        128,
        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
        32,
        "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb",
        0,
        NULL,
        32,
        "\x5e\xc8\x14\x3d\xe5\x09\xcf\xf7\xb5\x17\x9f\x8f\x47\x4b\x86\x19\x2f\x1d\x30\x5a\x7f\xb1\x7d\xf9\x85\xf8\x1c\x84\x82\x19\x23\x04",
    },
};

static const struct bc_test_pattern sm4_cfb_tp[] = {
    {
        SK_SM4,
        128,
        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
        32,
        "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        32,
        "\xac\x32\x36\xcb\x86\x1d\xd3\x16\xe6\x41\x3b\x4e\x3c\x75\x24\xb7\x69\xd4\xc5\x4e\xd4\x33\xb9\xa0\x34\x60\x09\xbe\xb3\x7b\x2b\x3f",
    },
};

static const struct bc_test_pattern sm4_ofb_tp[] = {
    {
        SK_SM4,
        128,
        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
        32,
        "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        32,
        "\xac\x32\x36\xcb\x86\x1d\xd3\x16\xe6\x41\x3b\x4e\x3c\x75\x24\xb7\x1d\x01\xac\xa2\x48\x7c\xa5\x82\xcb\xf5\x46\x3e\x66\x98\x53\x9b",
    },
};

static const struct bc_test_pattern sm4_cbc_tp[] = {
    {
        SK_SM4,
        128,
        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
        32,
        "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        32,
        "\x78\xeb\xb1\x1c\xc4\x0b\x0a\x48\x31\x2a\xae\xb2\x04\x02\x44\xcb\x4c\xb7\x01\x69\x51\x90\x92\x26\x97\x9b\x0d\x15\xdc\x6a\x8f\x6d",
    },
};

static const struct bc_test_pattern sm4_ctr_tp[] = {
    {
        SK_SM4,
        128,
        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
        64,
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xee\xee\xee\xee\xee\xee\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff\xee\xee\xee\xee\xee\xee\xee\xee\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        64,
        "\xac\x32\x36\xcb\x97\x0c\xc2\x07\x91\x36\x4c\x39\x5a\x13\x42\xd1\xa3\xcb\xc1\x87\x8c\x6f\x30\xcd\x07\x4c\xce\x38\x5c\xdd\x70\xc7\xf2\x34\xbc\x0e\x24\xc1\x19\x80\xfd\x12\x86\x31\x0c\xe3\x7b\x92\x2a\x46\xb8\x94\xbe\xe4\xfe\xb7\x9a\x38\x22\x94\x0c\x93\x54\x05",
    },
};

static const struct gcm_test_pattern {
    uint8_t cipher;
    uint32_t keybits;
    const void* key;
    uint32_t ptlen;
    const void* pt;
    uint32_t ivlen;
    const void* iv;
    uint32_t aadlen;
    const void* aad;
    uint32_t ctlen;
    const void* ct;
    uint32_t taglen;
    const void* tag;
} aes_gcm_tp[] = {
    {
        SK_AES,
        128,
        "\x11\x75\x4c\xd7\x2a\xec\x30\x9b\xf5\x2f\x76\x87\x21\x2e\x89\x57",
        0,
        "",
        12,
        "\x3c\x81\x9d\x9a\x9b\xed\x08\x76\x15\x03\x0b\x65",
        0,
        "",
        0,
        "",
        16,
        "\x25\x03\x27\xc6\x74\xaa\xf4\x77\xae\xf2\x67\x57\x48\xcf\x69\x71",
    },
    {
        SK_AES,
        128,
        "\x2f\xb4\x5e\x5b\x8f\x99\x3a\x2b\xfe\xbc\x4b\x15\xb5\x33\xe0\xb4",
        0,
        "",
        12,
        "\x5b\x05\x75\x5f\x98\x4d\x2b\x90\xf9\x4b\x80\x27",
        20,
        "\xe8\x54\x91\xb2\x20\x2c\xaf\x1d\x7d\xce\x03\xb9\x7e\x09\x33\x1c\x32\x47\x39\x41",
        0,
        "",
        16,
        "\xc7\x5b\x78\x32\xb2\xa2\xd9\xbd\x82\x74\x12\xb6\xef\x57\x69\xdb",
    },
    {
        SK_AES,
        128,
        "\xd0\xf1\xf4\xde\xfa\x1e\x8c\x08\xb4\xb2\x6d\x57\x63\x92\x02\x7c",
        0,
        "",
        128,
        "\x42\xb4\xf0\x1e\xb9\xf5\xa1\xea\x5b\x1e\xb7\x3b\x0f\xb0\xba\xed\x54\xf3\x87\xec\xaa\x03\x93\xc7\xd7\xdf\xfc\x6a\xf5\x01\x46\xec\xc0\x21\xab\xf7\xeb\x90\x38\xd4\x30\x3d\x91\xf8\xd7\x41\xa1\x17\x43\x16\x6c\x08\x60\x20\x8b\xcc\x02\xc6\x25\x8f\xd9\x51\x1a\x2f\xa6\x26\xf9\x6d\x60\xb7\x2f\xcf\xf7\x73\xaf\x4e\x88\xe7\xa9\x23\x50\x6e\x49\x16\xec\xbd\x81\x46\x51\xe9\xf4\x45\xad\xef\x4a\xd6\xa6\xb6\xc7\x29\x0c\xc1\x3b\x95\x61\x30\xee\xf5\xb8\x37\xc9\x39\xfc\xac\x0c\xbb\xcc\x96\x56\xcd\x75\xb1\x38\x23\xee\x5a\xcd\xac",
        0,
        "",
        0,
        "",
        16,
        "\x7a\xb4\x9b\x57\xdd\xf5\xf6\x2c\x42\x79\x50\x11\x1c\x5c\x4f\x0d",
    },
    {
        SK_AES,
        128,
        "\x5c\x78\x4f\xe5\x19\xcc\xd2\x94\xe9\x9b\x5c\x4f\x11\x27\xdb\x2e",
        0,
        "",
        128,
        "\x95\x93\x45\xfa\x5b\x2e\x0e\x76\x23\x2b\x2f\x7d\xf5\x07\x52\x92\x1a\x38\xbe\x3a\x25\xba\xdf\x6b\x57\x68\x20\xd9\x3a\x0d\x4e\x42\x8f\x2e\xe2\x89\x94\x95\xca\x49\x21\x42\xba\x4e\x2c\x14\x4f\x9f\x92\xa0\xd4\xf1\x7f\xa9\xba\xed\x7f\x49\x5b\x20\x00\xfb\xcb\xe3\x7f\x5b\x88\x73\xcc\xd1\x6f\x7d\x14\xfe\xf9\x0a\x7c\xff\x7e\xa2\x4e\xb7\xb5\x43\xf7\x80\xef\x84\x53\x09\x5d\xea\xea\x84\x2a\x95\x45\x03\x40\xd5\x94\x4c\x32\x55\xcb\xe0\x20\xec\xe9\x9c\xb7\xf3\xef\x03\xd1\xbb\x02\x51\x5d\x42\x55\x61\xad\xa5\x24\xb7\x0a\xb6",
        20,
        "\x46\xa6\x61\xfe\xb4\xa1\xad\x60\x7d\xcf\x75\x2e\x7f\x3f\x08\x9c\x3c\x33\x20\x8f",
        0,
        "",
        16,
        "\xa7\xd4\xf4\xb1\xfc\xa6\x7d\x7f\x0e\x63\x67\xb5\x8c\x27\x36\x10",
    },
    {
        SK_AES,
        128,
        "\x59\x41\x57\xec\x46\x93\x20\x2b\x03\x0f\x33\x79\x8b\x07\x17\x6d",
        51,
        "\x3f\xee\xf9\x8a\x97\x6a\x1b\xd6\x34\xf3\x64\xac\x42\x8b\xb5\x9c\xd5\x1f\xb1\x59\xec\x17\x89\x94\x69\x18\xdb\xd5\x0e\xa6\xc9\xd5\x94\xa3\xa3\x1a\x52\x69\xb0\xda\x69\x36\xc2\x9d\x06\x3a\x5f\xa2\xcc\x8a\x1c",
        12,
        "\x49\xb1\x20\x54\x08\x26\x60\x80\x3a\x1d\xf3\xdf",
        0,
        "",
        51,
        "\xc1\xb7\xa4\x6a\x33\x5f\x23\xd6\x5b\x8d\xb4\x00\x8a\x49\x79\x69\x06\xe2\x25\x47\x4f\x4f\xe7\xd3\x9e\x55\xbf\x2e\xfd\x97\xfd\x82\xd4\x16\x7d\xe0\x82\xae\x30\xfa\x01\xe4\x65\xa6\x01\x23\x5d\x8d\x68\xbc\x69",
        16,
        "\xba\x92\xd3\x66\x1c\xe8\xb0\x46\x87\xe8\x78\x8d\x55\x41\x7d\xc2",
    },
    {
        SK_AES,
        128,
        "\xfe\x47\xfc\xce\x5f\xc3\x26\x65\xd2\xae\x39\x9e\x4e\xec\x72\xba",
        51,
        "\x7c\x0e\x88\xc8\x88\x99\xa7\x79\x22\x84\x65\x07\x47\x97\xcd\x4c\x2e\x14\x98\xd2\x59\xb5\x43\x90\xb8\x5e\x3e\xef\x1c\x02\xdf\x60\xe7\x43\xf1\xb8\x40\x38\x2c\x4b\xcc\xaf\x3b\xaf\xb4\xca\x84\x29\xbe\xa0\x63",
        12,
        "\x5a\xdb\x96\x09\xdb\xae\xb5\x8c\xbd\x6e\x72\x75",
        20,
        "\x88\x31\x9d\x6e\x1d\x3f\xfa\x5f\x98\x71\x99\x16\x6c\x8a\x9b\x56\xc2\xae\xba\x5a",
        51,
        "\x98\xf4\x82\x6f\x05\xa2\x65\xe6\xdd\x2b\xe8\x2d\xb2\x41\xc0\xfb\xbb\xf9\xff\xb1\xc1\x73\xaa\x83\x96\x4b\x7c\xf5\x39\x30\x43\x73\x63\x65\x25\x3d\xdb\xc5\xdb\x87\x78\x37\x14\x95\xda\x76\xd2\x69\xe5\xdb\x3e",
        16,
        "\x29\x1e\xf1\x98\x2e\x4d\xef\xed\xaa\x22\x49\xf8\x98\x55\x6b\x47",
    },
    {
        SK_AES,
        128,
        "\x70\x5f\x69\xe8\x9b\xca\xba\x68\xc4\xc2\x6a\x9f\x7b\xf6\x94\x4c",
        51,
        "\x6a\x00\x06\xa3\x5f\x11\x51\x0d\x13\xfe\xe5\x82\x2b\xda\x90\x85\x76\xee\x97\x43\xb9\x5e\xea\x9e\xab\xa2\xc4\x57\xa8\xa5\x83\x8e\x56\xf6\xea\x6b\x85\xd3\x32\x84\x9d\xc6\x6a\x02\xde\xc2\x92\x55\x64\x28\xaf",
        128,
        "\x15\xb3\xbe\xa2\x67\x80\xdb\x69\x0e\xb2\xf7\x83\x54\x20\x72\x09\xc6\xc6\xf7\x0a\x1d\x18\xcb\x5e\xd6\x54\xa8\x1a\x6d\xa3\x30\x0d\x65\x3c\xfb\x54\xb5\xce\x8c\x32\x4f\x5e\x78\x47\x4d\x80\xde\x93\x80\xca\x77\xa8\x03\x7c\x2a\x7a\x16\x0f\xf3\x8a\x8b\x23\xa2\x0a\x68\x8f\xd8\xa5\xd1\xff\xce\x5a\xf7\xba\x37\x1e\x94\xde\x38\xb6\x65\x84\x71\xd2\xcc\xaf\x68\x4f\xad\x7a\xea\xe8\xb8\x0d\xf1\xa0\x95\x6b\x1c\x76\x7d\xe3\xd6\x86\xef\x56\xab\x77\x41\xb5\xf1\x5b\xbf\x7b\xb0\x02\x4b\x36\x2e\xa9\x79\x40\xd6\x93\x78\xa9\xb1\xe4",
        0,
        "",
        51,
        "\x8c\xfa\xaf\x97\xff\x27\xaa\x73\xfd\xba\xbd\x03\x87\x9b\x93\x7f\x66\x8d\xba\x79\xed\x9d\x73\xc7\xca\x46\x31\x75\x16\x61\x7c\x9b\x38\x4d\x93\x38\xb1\xa0\x87\xb2\x68\x87\x65\xa0\xdd\xe6\x38\x7f\x63\x50\xc0",
        16,
        "\x17\xcf\x37\x63\x99\x32\xf4\xce\x0e\x42\xdf\x06\x63\x53\x75\x6c",
    },
    {
        SK_AES,
        128,
        "\xc1\x15\xa6\x49\xeb\x2a\x50\x2f\xce\x0a\x7f\x55\x1d\x02\x00\xb7",
        51,
        "\x09\x62\xe1\x3f\x76\xe2\x81\x94\x2a\xec\x8c\x9d\x7b\xf5\x9c\xca\xf7\x02\xde\xa4\x9d\xe4\x84\x28\x0e\x4c\xc0\x7b\xf4\x43\x55\x62\x4d\x26\x2e\x5b\x42\xee\xff\x46\xa0\x6e\xb7\x98\xc0\xdc\xd7\x48\xaa\xeb\x66",
        128,
        "\x89\x62\xe4\xfe\xc5\xf0\x32\x13\x84\xba\x4e\x23\xcc\xa3\x5a\x04\x5b\xa2\xe6\x9c\x11\x64\x0f\xbd\x0a\xd6\x99\xa1\xfc\xa5\x22\xbd\xb8\xb8\x14\x95\xd2\xa1\xf5\x7f\xbf\x9c\x52\x0c\xd3\xec\x9a\xeb\xf3\xe4\x3b\x02\xd9\x78\x4a\x53\x2a\x97\xfa\xa6\xd0\xed\x17\xa1\xb9\x09\x6e\xe0\x47\xf0\xea\xe5\x04\x14\x96\x6b\x8c\xd6\x07\x12\x36\xd7\x05\x9a\x34\xc8\xdd\x1d\x9b\xa8\xac\x73\xd5\xd9\x30\x40\xef\x6a\xe6\x4f\xa9\xf5\x78\x6d\x4b\xa7\x18\x9b\x1b\xa8\x9d\x74\xae\xaf\x5e\x65\x60\x0f\x06\xc5\xd9\xfc\xf7\xc6\xe3\xd7\x6e\xc9",
        20,
        "\x2a\xb2\x86\x75\x68\x24\xc7\xc2\xd5\x3f\x98\xef\x70\x75\xfa\xe4\x18\x1b\xf7\x41",
        51,
        "\x8f\xe5\x9a\xa7\xc1\x12\xe4\xb5\x00\x0f\xd8\x2f\x19\x4f\x0f\x9b\x15\x21\x8f\x07\x26\x30\xdf\x58\x70\xd1\xc8\xca\x81\xd7\xd6\x6c\xcf\x95\xdd\xd3\xab\x3c\x60\x3a\xf2\xfc\x2b\xb9\xed\xca\x00\xc7\xbd\xab\x94",
        16,
        "\x9e\xab\x1e\x03\x7e\x70\x3a\x77\x7b\x76\x30\x6d\x8a\xa6\x60\xd3",
    },
    {
        SK_AES,
        192,
        "\xaa\x74\x0a\xbf\xad\xcd\xa7\x79\x22\x0d\x3b\x40\x6c\x5d\x7e\xc0\x9a\x77\xfe\x9d\x94\x10\x45\x39",
        0,
        "",
        12,
        "\xab\x22\x65\xb4\xc1\x68\x95\x55\x61\xf0\x43\x15",
        0,
        "",
        0,
        "",
        16,
        "\xf1\x49\xe2\xb5\xf0\xad\xaa\x98\x42\xca\x5f\x45\xb7\x68\xa8\xfc",
    },
    {
        SK_AES,
        192,
        "\x09\x3e\xf7\x55\x1e\xbb\xff\x8e\xb0\xc0\xa8\xa4\xa6\x2b\x19\x8f\x0c\x2e\x83\x8d\xe1\x0e\xee\xee",
        0,
        "",
        12,
        "\xe6\x56\xe9\x39\x30\xed\x52\x10\xba\x3f\x03\x22",
        20,
        "\x3d\xa2\x2d\xac\xfd\x11\xb2\x1b\x0a\x71\x31\x57\xf6\x0a\xec\x0c\xd2\x2f\x1a\xdd",
        0,
        "",
        16,
        "\x1b\x2d\x27\x64\x57\x3e\x20\xae\x64\x0b\xf2\x9d\x48\xe5\xfe\x05",
    },
    {
        SK_AES,
        192,
        "\xe2\xa1\xea\x08\xea\xa9\xa1\x91\x68\x51\xe5\xfb\xb9\xe9\xd4\x62\x8b\xd7\x04\xa7\x7d\x30\x6b\x40",
        0,
        "",
        128,
        "\x62\x6d\x60\x63\x0a\xbd\x85\x7f\xff\x55\x35\x43\x75\x4e\x9f\x3f\x35\x3f\xc8\x35\x45\xc1\xf7\x27\xe5\x8a\x3d\xfb\x5e\xe1\xb5\xf1\x79\x72\xa9\xfb\x1e\xd3\x60\x53\xf3\x90\x2d\x42\xd3\xfb\x01\xfc\xa5\x52\xef\x8b\x56\xe2\xb9\x79\x0c\x07\x05\xb8\x6f\x6b\x38\x61\x81\xda\xb5\xd0\x4b\x02\x17\x9b\xf8\x67\x97\xb2\xa0\x79\xfe\x85\x1f\x7b\x4c\xe2\x48\xdf\x03\xe8\xc1\xb6\x13\xba\xea\x10\xe1\x19\x2d\x39\x10\x49\x02\x64\x9c\x6c\x9c\x2a\x39\x68\x65\xf4\xff\x46\x91\x9e\xe8\x1b\xea\xcb\x9f\x5e\x9e\xa8\x5b\xbc\x88\x3b\x6a\x75",
        0,
        "",
        0,
        "",
        16,
        "\x58\x48\xc4\x39\x46\x71\x88\xc8\x65\x3e\x12\x9b\xa8\x6d\x96\xd8",
    },
    {
        SK_AES,
        192,
        "\x2a\x82\x1a\xa6\x6f\x0f\x69\x9a\xf6\x41\x5e\x82\x93\x24\xc9\xdf\x26\xa5\xf5\x52\x57\xb3\x12\x38",
        0,
        "",
        128,
        "\x19\x10\x0f\x8f\x71\x0b\xaf\xfd\x93\x6c\x50\x13\x72\x8d\x15\xbc\x69\xeb\x70\x84\xd1\xb2\x08\xb3\x4e\x23\x66\x11\x36\x16\xda\xa8\xef\x93\x2c\x4f\xa2\x4b\x86\xfc\x47\xc0\xb3\x30\x5f\x15\x04\x84\xeb\xb2\x86\x64\xf6\xc3\x2b\x81\xc7\x44\x4e\x73\x5d\x71\x91\x3f\xb2\xa2\x95\x48\x3b\x3b\x9d\x36\xc0\x08\x94\x62\xce\x3f\xf8\x85\xfa\x06\xd5\x1a\x7e\x93\x61\x0f\xa0\x83\x8e\x6d\xdb\x04\x27\xb0\xe7\xea\x53\xf1\xb8\x1d\x1e\x00\x62\xb7\x8c\xd8\x1d\x3c\xbf\xff\xec\xd1\xdd\xad\xd5\xbc\x2a\x28\x65\x28\x36\x80\x1c\x7b\xab\x96",
        20,
        "\x71\xc0\xa9\x7e\x6f\x85\xdd\xa4\x41\xe4\xb0\x22\xf7\x60\xe8\x42\x9f\x78\x0c\xca",
        0,
        "",
        16,
        "\x0f\x0e\xba\x58\x93\xf1\xf3\xd4\x03\xf0\x4e\x2e\x45\xfc\x4e\x60",
    },
    {
        SK_AES,
        192,
        "\xb3\x3a\x0d\x6e\xcb\x0a\x2c\x4e\x4d\xea\xb7\xe0\x65\x22\x7f\x7a\x5b\x05\x6f\x96\xec\xab\x37\x61",
        51,
        "\xa8\xbe\xff\x90\x51\x9d\x7e\x53\x7b\x0f\x95\xf9\x7b\x9e\xbc\xd4\xd7\x1f\xce\x3e\x59\xf8\x7c\xc4\x3c\xc4\xf7\x45\x33\x19\xc9\x73\xa4\xdd\x47\xcf\x4d\x70\x62\xb0\x01\xe5\x28\x28\xee\x54\x5a\x0a\xe2\x7e\x46",
        12,
        "\x46\x4e\x4e\xa7\x5b\x77\xe7\xa1\xfa\x33\x03\x72",
        0,
        "",
        51,
        "\xa6\xf8\x56\x4d\x9a\x49\x13\xfb\x36\x6f\x83\x28\x9f\xfe\xbc\x7e\xeb\x3e\x24\x0a\xc2\xf4\x03\x08\x83\xa2\x8e\x27\x78\x45\x88\x94\xf7\xad\x7d\x8f\x3e\x9a\x8c\xe3\x2b\x27\xa0\x24\x9f\x0c\x22\x45\x4d\x7c\x0d",
        16,
        "\xd0\x94\xb9\x77\x85\xb7\xe0\xb0\x9d\xc0\x00\x8f\x4f\x0d\xa9\xd7",
    },
    {
        SK_AES,
        192,
        "\x99\x00\x22\x7a\xe0\xfc\xcb\xb0\xd3\x5e\xcf\x95\x46\x29\xc9\x69\xf3\x6e\x53\x93\x99\xf3\x2e\xbe",
        51,
        "\x9d\x42\x27\xee\xd2\x8b\x97\x38\xf2\x15\x41\xc4\x75\x5a\x92\x3a\x43\xba\x20\xd6\xf3\xd6\xa6\xb7\xe3\x1e\x56\xf1\x50\x2f\x5e\x93\xed\x4c\x00\x51\x1c\x6a\x7d\xae\xb0\x28\x1a\xb9\x47\xe9\x17\x56\x63\x81\x54",
        12,
        "\x13\x98\x99\x2b\xfb\xd6\x31\x49\xc1\x4b\xa2\xa2",
        20,
        "\x78\x8b\x68\x85\xfe\xff\x23\xfc\x27\xbf\x9c\x46\x28\x77\xb6\x42\xba\x1a\xa6\x8d",
        51,
        "\x7b\x6e\xe7\xdd\x98\xed\xa9\xb2\x0e\xdb\x41\x47\x11\xd9\x71\x0d\xe4\x02\xb0\x19\x50\xa6\x71\x2e\x58\x09\xf6\x08\xf7\xc0\xaa\x0f\xba\x40\x98\xf1\x45\xfe\xa6\x88\x6d\x7b\xaf\x51\xfc\xd1\x82\xc8\xfe\xbf\x49",
        16,
        "\xf2\x2c\x7c\x21\xf5\xec\xe2\xde\x68\x48\x21\x09\x21\x94\xf2\x6c",
    },
    {
        SK_AES,
        192,
        "\xcf\xac\x71\x49\x77\x7a\xa3\xc7\xd0\x83\x0c\x0c\x5e\x57\x17\x7e\x61\x79\x81\x0c\x0b\x03\x42\xa1",
        51,
        "\x69\x1d\x74\xa2\x28\xe2\x97\x6e\x81\xe7\xc8\x0d\x5b\x80\xf9\xa0\xd6\xc4\xcf\x2e\xfa\xc3\x9b\xb2\x6a\x12\x4f\x0c\x48\x87\x73\x62\x61\x20\x95\x99\xdf\xf6\x19\x62\x93\x7e\x51\xa0\x27\x1d\x61\xed\x2f\xf0\x3c",
        128,
        "\x33\xaf\xa5\x4b\xcf\xd3\xd8\x60\xe2\x1f\x39\xae\x62\x4e\x93\x41\xf1\x3d\xeb\x30\x73\x33\xe0\x19\x43\x79\xd3\xb5\xaf\xc9\xc0\x8a\x31\xa0\xf3\x1d\x3c\xbb\x10\xcb\xf7\x0f\xcb\x3a\x36\x95\x8a\x34\x13\x01\xa0\x62\x62\x23\x95\x58\x08\xef\x22\xfd\x83\xf7\x5e\xb8\x52\x09\xc5\x2e\xb6\x1e\xa6\x5f\xef\x26\xa2\xc2\x2f\xbc\x50\xbd\x97\x50\x86\x23\x70\xeb\xec\xde\x41\x02\x18\xee\x84\x7a\xa5\xd3\x99\x60\xf8\x30\x79\xf6\x60\x30\x3f\x70\xcf\x2c\x6f\x24\x3a\x36\x2e\x4e\x54\x62\x8b\x64\x8b\x83\xfc\xed\x42\x0f\xe2\xee\x13\x6c",
        0,
        "",
        51,
        "\x14\x5b\xeb\x0d\x35\xcf\xf0\xe2\x2a\xed\x59\x35\x52\x47\x6d\xc4\xa2\x82\xb7\x7e\xe3\x33\x2e\xac\xc9\x99\x09\xff\x56\x3e\xad\xf2\xc4\x56\xea\x13\x0a\x1d\x11\x28\x76\xcf\x32\xe3\x31\xf6\xed\x8d\x7b\xe8\x6a",
        16,
        "\xbb\x92\x11\xeb\x25\x91\xa5\xd0\xdb\x72\x9d\x5d\xda\x31\x2a\x01",
    },
    {
        SK_AES,
        192,
        "\x3f\x41\xc6\xfe\x02\x50\x83\xa3\xcd\x3e\x26\x73\x37\x06\xb2\xf7\x5c\x56\x70\x23\xb8\xd7\x57\x0e",
        51,
        "\x0b\x5f\x3e\xbc\xf9\x09\xe7\xf6\x44\x0c\x34\x49\x5f\xe3\x68\xe8\x00\xec\xaa\x2f\xbe\x1b\x75\x7a\x83\x37\x34\xb7\xc8\x00\xe2\xed\x17\x8c\xe0\x40\xda\x02\x4f\xe9\xc2\x0d\x33\x92\x49\x4e\x5c\x2d\x99\x28\xd0",
        128,
        "\x7e\x1b\xb5\xed\xaf\xa9\xaf\x0d\x54\xf9\xa3\xfc\x08\x7b\x36\x67\xfb\x04\xf3\xb0\xc4\x8f\xa6\xa5\xe2\xa4\xef\x71\x4a\x84\x7c\xca\xd1\x6b\xfc\x1f\x3a\x64\xb0\xb7\x18\xd1\xd4\x17\x84\xee\xa7\xdb\x6c\xb1\x67\x36\x71\x4f\x92\x71\xa0\xb8\x03\xf2\x15\xf9\x9c\x12\x54\xde\x1e\x94\xd5\x27\x3a\xb6\xb5\x22\x12\x04\x62\xa8\xfb\xd5\x92\xfa\xc0\xca\xab\x35\x4b\xde\x39\x99\x99\xdd\x8a\x18\x75\xc9\x28\x0c\x66\x64\xc5\x61\xb9\xd2\x83\xd3\x29\xb6\xb0\xf2\x0a\xdd\xd1\xd9\xab\x48\x3e\x31\xf2\x05\x75\x70\x76\x52\xbe\x8c\x56\xaf",
        20,
        "\x98\xa6\x63\x53\xc9\xae\xe8\x61\x1c\x54\xe6\x9f\xce\xcb\xb7\x3d\xde\xb6\xde\x7e",
        51,
        "\xc2\x32\xdb\x53\xd6\x41\xd1\xea\x94\x28\x81\x34\x97\xc8\xce\xb4\xc0\xbe\x9f\xb3\xf2\xcf\xe5\x52\x7f\xce\xf5\x14\x8e\x83\x57\x2d\xf2\xb4\xc2\xfc\x8c\x75\xd1\x40\x92\x89\x04\x1e\x88\x2d\x5b\xa4\x23\x12\xed",
        16,
        "\xb6\x99\xe6\x47\x60\x08\xa8\x36\x6e\x7a\x70\x7a\x42\x41\x38\x22",
    },
    {
        SK_AES,
        256,
        "\xb5\x2c\x50\x5a\x37\xd7\x8e\xda\x5d\xd3\x4f\x20\xc2\x25\x40\xea\x1b\x58\x96\x3c\xf8\xe5\xbf\x8f\xfa\x85\xf9\xf2\x49\x25\x05\xb4",
        0,
        "",
        12,
        "\x51\x6c\x33\x92\x9d\xf5\xa3\x28\x4f\xf4\x63\xd7",
        0,
        "",
        0,
        "",
        16,
        "\xbd\xc1\xac\x88\x4d\x33\x24\x57\xa1\xd2\x66\x4f\x16\x8c\x76\xf0",
    },
    {
        SK_AES,
        256,
        "\x88\x6c\xff\x5f\x3e\x6b\x8d\x0e\x1a\xd0\xa3\x8f\xcd\xb2\x6d\xe9\x7e\x8a\xcb\xe7\x9f\x6b\xed\x66\x95\x9a\x59\x8f\xa5\x04\x7d\x65",
        0,
        "",
        12,
        "\x3a\x8e\xfa\x1c\xd7\x4b\xba\xb5\x44\x8f\x99\x45",
        20,
        "\x51\x9f\xee\x51\x9d\x25\xc7\xa3\x04\xd6\xc6\xaa\x18\x97\xee\x1e\xb8\xc5\x96\x55",
        0,
        "",
        16,
        "\xf6\xd4\x75\x05\xec\x96\xc9\x8a\x42\xdc\x3a\xe7\x19\x87\x7b\x87",
    },
    {
        SK_AES,
        256,
        "\x88\x76\x83\x54\xdf\x41\x4c\xe4\x09\x7f\x4d\x35\x78\x37\x11\x66\x85\xbe\xee\x0d\x93\xaa\xb3\x43\x57\x6b\x89\x30\x88\x25\x62\x60",
        0,
        "",
        128,
        "\xf6\x49\xd3\x75\xe4\xe8\x96\x39\x7a\x8a\x96\xcb\xb8\x47\xfb\xf4\x5c\xb5\x41\x32\xc7\x6b\xaf\x81\x4f\x4e\x35\xe9\xf7\x73\x7f\x16\xd5\xcd\x71\x03\x70\xf1\x43\x61\x2b\x46\x72\x4b\xbd\xde\xd2\xa2\x62\x64\xb9\x0a\x91\xf5\xed\x42\x5d\x08\xd3\x17\xf4\x9a\x56\x82\x8f\xcf\xeb\x9e\xbe\x1b\xc5\x31\x17\xbb\x41\x56\xc2\xe9\x9d\x70\xb2\x38\xdd\x91\x66\xcc\x05\x90\x67\x19\x81\x80\x22\xc7\x59\x57\xd2\x5a\xd9\xc3\x6c\x93\xce\x26\x26\x24\x8c\x78\x3e\x02\x07\xc3\x5d\xb7\x49\x96\xf4\x7d\x09\x6c\x3c\xaf\xe7\x01\xa3\x81\x54\xce",
        0,
        "",
        0,
        "",
        16,
        "\x90\x5b\x22\xcd\x3f\xe7\x76\x45\xe6\xa2\x17\xdd\x1f\x99\x3e\xc4",
    },
    {
        SK_AES,
        256,
        "\xab\x23\xed\xd2\x2f\x17\xf1\x2b\xab\xe9\xfb\xa5\x4c\xda\xf6\x02\x03\x92\xb0\x14\xaf\x96\x95\xf4\x0c\xab\x22\xeb\x52\x97\xda\xac",
        0,
        "",
        128,
        "\x01\xe4\x14\xe2\xb0\x93\x97\xae\xda\xdd\x70\x32\x08\x5a\xbf\x09\x59\xee\xca\x92\xe4\x64\x76\xf9\x2b\xd1\x81\x09\xc8\x61\x69\x2b\x01\x39\x6d\x23\x87\xc8\x1c\x82\x7b\xb4\x06\x6f\xba\x06\x1d\xba\xca\x85\x06\xac\xcc\x9c\xe1\x32\x68\x1c\x67\x05\x65\x82\xf5\xf7\x53\xd5\xb1\xf1\x58\xaf\x69\xe1\x2e\x16\xae\x1a\x44\xaf\x38\x16\xb5\x76\xeb\xd4\xec\xe0\xd4\x07\x06\xe6\xd3\x53\x52\xf7\xd2\x3a\xa8\x9f\x3e\x26\xfd\xb8\x1e\x70\xa0\xb5\x35\x52\x33\x1b\xce\x0b\x52\x1e\xcd\x47\x6f\x3c\x2d\x2a\xa8\x2b\x24\xf4\xa1\x60\x14\x06",
        20,
        "\x46\x9a\x5c\x30\xc6\xc7\xf0\x9c\x95\xa8\x68\x12\xd8\x2e\x1a\x64\x87\x15\x36\x51",
        0,
        "",
        16,
        "\xf3\x6f\x9b\x8d\xc9\xb3\x72\x64\x4b\x29\xfb\x2a\x94\x53\x6f\x42",
    },
    {
        SK_AES,
        256,
        "\x1f\xde\xd3\x2d\x59\x99\xde\x4a\x76\xe0\xf8\x08\x21\x08\x82\x3a\xef\x60\x41\x7e\x18\x96\xcf\x42\x18\xa2\xfa\x90\xf6\x32\xec\x8a",
        51,
        "\x06\xb2\xc7\x58\x53\xdf\x9a\xeb\x17\xbe\xfd\x33\xce\xa8\x1c\x63\x0b\x0f\xc5\x36\x67\xff\x45\x19\x9c\x62\x9c\x8e\x15\xdc\xe4\x1e\x53\x0a\xa7\x92\xf7\x96\xb8\x13\x8e\xea\xb2\xe8\x6c\x7b\x7b\xee\x1d\x40\xb0",
        12,
        "\x1f\x3a\xfa\x47\x11\xe9\x47\x4f\x32\xe7\x04\x62",
        0,
        "",
        51,
        "\x91\xfb\xd0\x61\xdd\xc5\xa7\xfc\xc9\x51\x3f\xcd\xfd\xc9\xc3\xa7\xc5\xd4\xd6\x4c\xed\xf6\xa9\xc2\x4a\xb8\xa7\x7c\x36\xee\xfb\xf1\xc5\xdc\x00\xbc\x50\x12\x1b\x96\x45\x6c\x8c\xd8\xb6\xff\x1f\x8b\x3e\x48\x0f",
        16,
        "\x30\x09\x6d\x34\x0f\x3d\x5c\x42\xd8\x2a\x6f\x47\x5d\xef\x23\xeb",
    },
    {
        SK_AES,
        256,
        "\x24\x50\x1a\xd3\x84\xe4\x73\x96\x3d\x47\x6e\xdc\xfe\x08\x20\x52\x37\xac\xfd\x49\xb5\xb8\xf3\x38\x57\xf8\x11\x4e\x86\x3f\xec\x7f",
        51,
        "\x27\xf3\x48\xf9\xcd\xc0\xc5\xbd\x5e\x66\xb1\xcc\xb6\x3a\xd9\x20\xff\x22\x19\xd1\x4e\x8d\x63\x1b\x38\x72\x26\x5c\xf1\x17\xee\x86\x75\x7a\xcc\xb1\x58\xbd\x9a\xbb\x38\x68\xfd\xc0\xd0\xb0\x74\xb5\xf0\x1b\x2c",
        12,
        "\x9f\xf1\x85\x63\xb9\x78\xec\x28\x1b\x3f\x27\x94",
        20,
        "\xad\xb5\xec\x72\x0c\xcf\x98\x98\x50\x00\x28\xbf\x34\xaf\xcc\xbc\xac\xa1\x26\xef",
        51,
        "\xeb\x7c\xb7\x54\xc8\x24\xe8\xd9\x6f\x7c\x6d\x9b\x76\xc7\xd2\x6f\xb8\x74\xff\xbf\x1d\x65\xc6\xf6\x4a\x69\x8d\x83\x9b\x0b\x06\x14\x5d\xae\x82\x05\x7a\xd5\x59\x94\xcf\x59\xad\x7f\x67\xc0\xfa\x5e\x85\xfa\xb8",
        16,
        "\xbc\x95\xc5\x32\xfe\xcc\x59\x4c\x36\xd1\x55\x02\x86\xa7\xa3\xf0",
    },
    {
        SK_AES,
        256,
        "\x81\x64\x58\xa5\xbd\xf7\xf9\x37\x65\x3d\x1b\xc1\xc7\x96\x99\xc0\xe3\x29\x1f\x03\xb3\xf6\xbe\x8c\x76\xcf\xb9\x2f\xd5\x44\xd2\x27",
        51,
        "\x61\x64\x5d\x5f\x85\x7d\x11\x75\x6f\xc4\x3f\x5f\xd7\xbd\xd0\x03\x07\x9a\x58\xa4\x22\x87\x34\x5e\x7c\x74\x4d\xd8\x8f\xaf\x25\x15\x4d\x02\x91\x1f\x2b\x22\xe6\x14\x08\x73\x2a\xb4\xbd\xbe\xc2\xe9\xb9\xd9\x42",
        128,
        "\xee\x87\xab\xc8\x5b\xc7\x36\xb6\xe5\x9b\x02\xeb\x36\x95\x5c\x05\xcb\x2a\x0f\xfc\xc5\xd3\x40\x91\x84\x3a\x54\xca\x0a\xbe\xdc\xb5\x9e\xd2\x15\xca\x3a\xe3\x83\x5f\xc4\x2c\x38\x32\xcc\x66\x23\xdc\x6d\x07\xcb\x48\x19\x83\x66\xd4\x71\xa3\xa0\x6f\x4c\xe9\x3e\xbe\xc0\x4e\x2f\x0e\xa6\xaa\x92\xf0\x7c\x4b\x21\x62\x4b\x3a\xa3\x20\x22\x79\xb9\x5c\x19\xe9\x4c\x3c\x3e\xc7\x9a\x83\x10\xe7\x40\x1e\x5b\x45\x48\xbd\x2a\x1e\x69\xb9\x48\xf2\xc3\xb3\x4c\x9c\x4e\x11\x54\xf4\xf0\xd2\x87\xae\xea\xb8\x38\x80\x97\xa0\xcb\x9b\x11\x04",
        0,
        "",
        51,
        "\x21\x3c\xcc\xac\x33\x12\x29\xab\xd6\x21\xee\xf6\x8d\x63\x2c\xb0\x9b\xff\x70\x5f\x8b\x02\x17\x3d\x24\xa5\x03\x8d\x89\xd2\x87\x52\x0f\xf2\x66\x19\xa2\xdd\xcc\xdc\xa8\x9f\xc2\x54\xaa\x17\x85\x6c\x27\xcb\x26",
        16,
        "\x81\x4d\xcb\x36\xd1\x0b\xa5\x80\x3c\x31\x1a\x54\xd3\x47\x35\xf6",
    },
    {
        SK_AES,
        256,
        "\xa1\x5d\x2e\xd3\xc7\x68\x7a\xe9\xed\x64\x2c\xdc\x14\x09\x67\x34\x89\xa1\x45\x9d\xbc\xae\x0e\xf0\x27\xee\x21\x8a\x85\xa2\xd7\x4a",
        51,
        "\xbd\x91\x23\xa1\x98\x39\x3b\x46\x4d\x13\xd5\x03\x41\xb9\x73\x13\xc1\x7d\x51\xce\x52\x71\x36\x85\x7a\xf0\xb3\x68\xde\x29\xb6\xbc\xf6\x66\xdf\xed\x00\x16\xf9\x63\xac\xd2\x17\x32\xc7\xab\x21\x62\xa8\x1a\x95",
        128,
        "\xfa\xa4\x48\x46\xe5\xa4\x8c\x0e\xe8\xb3\x3d\x83\x73\x43\x6d\x0f\x67\x95\x08\x97\xc2\xf6\x0d\x8e\x84\x2d\x1e\x52\xa0\x87\x92\xe8\x54\x52\x3b\x06\x90\x48\xf0\x96\x76\x4c\x0a\xc1\x86\xdf\x06\xb7\x3b\xd7\x5e\x92\xde\x5c\xe1\x5b\x0d\x4a\x9c\xe3\x88\xe4\xce\x56\x89\xb7\x88\xb5\x31\x99\xf2\xe4\x79\xfc\x72\x0e\xab\xcb\x36\xa9\xd4\xa2\x76\x51\x4e\x12\xce\xd8\x2b\x15\xad\x4f\xca\x9c\xe0\x5c\x97\x5a\xf9\x39\x11\x31\x32\xb8\x59\xeb\xeb\xa8\xc3\xfc\xaa\x0f\x25\x73\x29\x17\x60\xf0\xf8\x2b\x5d\xd6\xdb\x51\x50\x77\x60\x68",
        20,
        "\x45\xfd\x13\x9a\xd6\x99\x79\xf4\x8d\x15\x4b\x00\xee\x81\xe4\x17\xca\x50\x0e\xf9",
        51,
        "\x06\x8b\x89\x54\x0a\x85\x82\x3c\x32\xd6\xce\xfd\x94\x75\x53\x19\x9a\x5d\x15\x7f\x5a\x26\x11\xd4\x58\x20\x08\xb8\x2c\x5d\x17\x6d\x43\xe9\x4a\xcd\x9f\x0c\xdd\x3c\x6a\x48\x43\x61\x4a\xbf\x71\xa5\x24\x2d\x9d",
        16,
        "\xba\xc6\x69\x92\x74\x9f\xd1\x78\x0b\x21\xc9\xd4\x1b\x12\x88\xd4",
    },
};

static const struct ccm_test_pattern {
    uint8_t cipher;
    uint32_t keybits;
    const void* key;
    uint32_t ptlen;
    const void* pt;
    uint32_t noncelen;
    const void* nonce;
    uint32_t aadlen;
    const void* aad;
    uint32_t ctlen;
    const void* ct;
    uint32_t taglen;
    const void* tag;
} aes_ccm_tp[] = {
    {
        SK_AES,
        128,
        "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
        4,
        "\x20\x21\x22\x23",
        7,
        "\x10\x11\x12\x13\x14\x15\x16",
        8,
        "\x00\x01\x02\x03\x04\x05\x06\x07",
        4,
        "\x71\x62\x01\x5b",
        4,
        "\x4d\xac\x25\x5d",
    },
    {
        SK_AES,
        128,
        "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
        16,
        "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f",
        8,
        "\x10\x11\x12\x13\x14\x15\x16\x17",
        16,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
        16,
        "\xd2\xa1\xf0\xe0\x51\xea\x5f\x62\x08\x1a\x77\x92\x07\x3d\x59\x3d",
        6,
        "\x1f\xc6\x4f\xbf\xac\xcd",
    },
    {
        SK_AES,
        128,
        "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
        24,
        "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37",
        12,
        "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b",
        20,
        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13",
        24,
        "\xe3\xb2\x01\xa9\xf5\xb7\x1a\x7a\x9b\x1c\xea\xec\xcd\x97\xe7\x0b\x61\x76\xaa\xd9\xa4\x42\x8a\xa5",
        8,
        "\x48\x43\x92\xfb\xc1\xb0\x99\x51",
    },
    {
        SK_AES,
        128,
        "\xd2\x4a\x3d\x3d\xde\x8c\x84\x83\x02\x80\xcb\x87\xab\xad\x0b\xb3",
        24,
        "\x7c\x86\x13\x5e\xd9\xc2\xa5\x15\xaa\xae\x0e\x9a\x20\x81\x33\x89\x72\x69\x22\x0f\x30\x87\x00\x06",
        13,
        "\xf1\x10\x00\x35\xbb\x24\xa8\xd2\x60\x04\xe0\xe2\x4b",
        0,
        NULL,
        24,
        "\x1f\xae\xb0\xee\x2c\xa2\xcd\x52\xf0\xaa\x39\x66\x57\x83\x44\xf2\x4e\x69\xb7\x42\xc4\xab\x37\xab",
        16,
        "\x11\x23\x30\x12\x19\xc7\x05\x99\xb7\xc3\x73\xad\x4b\x3a\xd6\x7b",
    },
    {
        SK_AES,
        128,
        "\x2e\xbf\x60\xf0\x96\x90\x13\xa5\x4a\x3d\xed\xb1\x9d\x20\xf6\xc8",
        0,
        NULL,
        13,
        "\x1d\xe8\xc5\xe2\x1f\x9d\xb3\x31\x23\xff\x87\x0a\xdd",
        32,
        "\xe1\xde\x6c\x61\x19\xd7\xdb\x47\x11\x36\x28\x5d\x10\xb4\x7a\x45\x02\x21\xb1\x69\x78\x56\x91\x90\xef\x6a\x22\xb0\x55\x29\x56\x03",
        0,
        NULL,
        16,
        "\x0e\xad\x29\xef\x20\x5f\xbb\x86\xd1\x1a\xbe\x5e\xd7\x04\xb8\x80",
    },
};

static const struct bc_test_pattern aes_xts_tp[] = {
    {
        SK_AES,
        128,
        "\xa1\xb9\x0c\xba\x3f\x06\xac\x35\x3b\x2c\x34\x38\x76\x08\x17\x62\x09\x09\x23\x02\x6e\x91\x77\x18\x15\xf2\x9d\xab\x01\x93\x2f\x2f",
        16,
        "\xeb\xab\xce\x95\xb1\x4d\x3c\x8d\x6f\xb3\x50\x39\x07\x90\x31\x1c",
        16,
        "\x4f\xae\xf7\x11\x7c\xda\x59\xc6\x6e\x4b\x92\x01\x3e\x76\x8a\xd5",
        16,
        "\x77\x8a\xe8\xb4\x3c\xb9\x8d\x5a\x82\x50\x81\xd5\xbe\x47\x1c\x63",
    },
    {
        SK_AES,
        128,
        "\x39\x4c\x97\x88\x1a\xbd\x98\x9d\x29\xc7\x03\xe4\x8a\x72\xb3\x97\xa7\xac\xf5\x1b\x59\x64\x9e\xee\xa9\xb3\x32\x74\xd8\x54\x1d\xf4",
        25,
        "\x2f\x3b\x9d\xcf\xba\xe7\x29\x58\x3b\x1d\x1f\xfd\xd1\x6b\xb6\xfe\x27\x57\x32\x94\x35\x66\x2a\x78\xf0",
        16,
        "\x4b\x15\xc6\x84\xa1\x52\xd4\x85\xfe\x99\x37\xd3\x9b\x16\x8c\x29",
        25,
        "\xf3\x47\x38\x02\xe3\x8a\x3f\xfe\xf4\xd4\xfb\x8e\x6a\xa2\x66\xeb\xde\x55\x3a\x64\x52\x8a\x06\x46\x3e",
    },
    {
        SK_AES,
        128,
        "\x66\xc2\x1c\x85\x9d\x40\xbc\x38\x47\x25\x62\x6c\x79\x3f\xe8\x82\xb0\xf1\x1a\x39\x7c\x63\xaa\xc2\x02\x6c\xc8\xda\x89\x16\xfb\xad",
        32,
        "\xa8\xac\x2b\xba\x1d\x5d\xe9\x39\x67\x9f\xbe\x3b\x97\x59\x09\x49\x01\x72\xfe\x86\x0e\x6c\x24\xc7\x07\x63\x74\xdc\x0c\xaf\x55\x35",
        16,
        "\x68\x86\xce\x72\x37\x03\x1d\x39\x63\xaf\x24\xef\x3d\x20\xf7\xed",
        32,
        "\x3c\x21\x49\x04\x07\x2f\xc4\xac\x45\xa2\x24\x53\x41\xf7\x8b\x78\x73\xf0\x5d\x32\x55\xd3\x40\x11\x5a\x92\x0d\x0b\xf2\xab\xf6\x71",
    },
    {
        SK_AES,
        256,
        "\x1e\xa6\x61\xc5\x8d\x94\x3a\x0e\x48\x01\xe4\x2f\x4b\x09\x47\x14\x9e\x7f\x9f\x8e\x3e\x68\xd0\xc7\x50\x52\x10\xbd\x31\x1a\x0e\x7c\xd6\xe1\x3f\xfd\xf2\x41\x8d\x8d\x19\x11\xc0\x04\xcd\xa5\x8d\xa3\xd6\x19\xb7\xe2\xb9\x14\x1e\x58\x31\x8e\xea\x39\x2c\xf4\x1b\x08",
        32,
        "\x2e\xed\xea\x52\xcd\x82\x15\xe1\xac\xc6\x47\xe8\x10\xbb\xc3\x64\x2e\x87\x28\x7f\x8d\x2e\x57\xe3\x6c\x0a\x24\xfb\xc1\x2a\x20\x2e",
        16,
        "\xad\xf8\xd9\x26\x27\x46\x4a\xd2\xf0\x42\x8e\x84\xa9\xf8\x75\x64",
        32,
        "\xcb\xaa\xd0\xe2\xf6\xce\xa3\xf5\x0b\x37\xf9\x34\xd4\x6a\x9b\x13\x0b\x9d\x54\xf0\x7e\x34\xf3\x6a\xf7\x93\xe8\x6f\x73\xc6\xd7\xdb",
    },
    {
        SK_AES,
        256,
        "\x88\xdf\xd7\xc8\x3c\xb1\x21\x96\x8f\xeb\x41\x75\x20\x55\x5b\x36\xc0\xf6\x3b\x66\x25\x70\xea\xc1\x2e\xa9\x6c\xbe\x18\x8a\xd5\xb1\xa4\x4d\xb2\x3a\xc6\x47\x03\x16\xcb\xa0\x04\x1c\xad\xf2\x48\xf6\xd9\xa7\x71\x3f\x45\x4e\x66\x3f\x3e\x39\x87\x58\x5c\xeb\xbf\x96",
        48,
        "\xec\x36\x55\x1c\x70\xef\xcd\xf8\x5d\xe7\xa3\x99\x88\x97\x82\x63\xad\x26\x1e\x83\x99\x6d\xad\x21\x9a\x00\x58\xe0\x21\x87\x38\x4f\x2d\x07\x54\xff\x9c\xfa\x00\x0b\xec\x44\x8f\xaf\xd2\xcf\xa7\x38",
        16,
        "\x0e\xe8\x46\x32\xb8\x38\xdd\x52\x8f\x1d\x96\xc7\x64\x39\x80\x5c",
        48,
        "\xa5\x5d\x53\x3c\x9c\x58\x85\x56\x2b\x92\xd4\x58\x2e\xa6\x9d\xb8\xe2\xba\x9c\x0b\x96\x7a\x9f\x01\x67\x70\x0b\x04\x35\x25\xa4\x7b\xaf\xe7\xd6\x30\x77\x4e\xaf\x4a\x1d\xc9\xfb\xcf\x94\xa1\xfd\xa4",
    },
};

static int bc_test(uint8_t mode, const struct bc_test_pattern* tp, uint32_t count)
{
    int ret;
    int fd;
    uint8_t* out;
    uint32_t outlen, toutlen;
    pufs_skcipher_init_t init;
    pufs_skcipher_update_t update;
    pufs_skcipher_final_t final;

    fd = open("/dev/pufs", O_RDWR);
    if (fd < 0) {
        printf("open /dev/pufs err!\n");
        printf("Fail!\n");
        return -1;
    }

    for (int i = 0; i < count; i++) {
        printf("case %d encrypt, pclen = %d\n", i, tp[i].ptlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = mode;
        init.encrypt = 1;
        init.aes.keytype = KT_SWKEY;
        init.aes.keyaddr = (void*)tp[i].key;
        init.aes.keybits = tp[i].keybits;
        init.aes.iv = (void*)tp[i].iv;
        init.aes.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ctlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].pt;
        update.inlen = tp[i].ptlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ctlen) || (memcmp(out, tp[i].ct, toutlen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);

        printf("case %d decrypt, ctlen = %d\n", i, tp[i].ctlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = mode;
        init.encrypt = 0;
        init.aes.keytype = KT_SWKEY;
        init.aes.keyaddr = (void*)tp[i].key;
        init.aes.keybits = tp[i].keybits;
        init.aes.iv = (void*)tp[i].iv;
        init.aes.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ptlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].ct;
        update.inlen = tp[i].ctlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ptlen) || (memcmp(out, tp[i].pt, toutlen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);
    }

    close(fd);

    if (ret == 0)
        printf("Success!\n");
    else
        printf("Fail!\n");

    return ret;
}

static int gcm_test(const struct gcm_test_pattern* tp, uint32_t count)
{
    int ret;
    int fd;
    uint8_t tag[64];
    uint8_t* out;
    uint32_t outlen, toutlen;
    pufs_skcipher_init_t init;
    pufs_skcipher_update_t update;
    pufs_skcipher_final_t final;

    fd = open("/dev/pufs", O_RDWR);
    if (fd < 0) {
        printf("open /dev/pufs err!\n");
        printf("Fail!\n");
        return -1;
    }

    for (int i = 0; i < count; i++) {
        printf("case %d encrypt, pclen = %d\n", i, tp[i].ptlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_GCM;
        init.encrypt = 1;
        init.aes_gcm.keytype = KT_SWKEY;
        init.aes_gcm.keyaddr = (void*)tp[i].key;
        init.aes_gcm.keybits = tp[i].keybits;
        init.aes_gcm.iv = (void*)tp[i].iv;
        init.aes_gcm.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update aad
        update.out = NULL;
        update.outlen = NULL;
        update.in = (void*)tp[i].aad;
        update.inlen = tp[i].aadlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ctlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].pt;
        update.inlen = tp[i].ptlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        final.tag = tag;
        final.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ctlen) || (memcmp(out, tp[i].ct, toutlen) != 0) || (memcmp(tag, tp[i].tag, tp[i].taglen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);

        printf("case %d decrypt, ctlen = %d\n", i, tp[i].ctlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_GCM;
        init.encrypt = 0;
        init.aes_gcm.keytype = KT_SWKEY;
        init.aes_gcm.keyaddr = (void*)tp[i].key;
        init.aes_gcm.keybits = tp[i].keybits;
        init.aes_gcm.iv = (void*)tp[i].iv;
        init.aes_gcm.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update aad
        update.out = NULL;
        update.outlen = NULL;
        update.in = (void*)tp[i].aad;
        update.inlen = tp[i].aadlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ptlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].ct;
        update.inlen = tp[i].ctlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        final.tag = tag;
        final.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ptlen) || (memcmp(out, tp[i].pt, toutlen) != 0) || (memcmp(tag, tp[i].tag, tp[i].taglen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);
    }

    close(fd);

    if (ret == 0)
        printf("Success!\n");
    else
        printf("Fail!\n");

    return ret;
}

static int ccm_test(const struct ccm_test_pattern* tp, uint32_t count)
{
    int ret;
    int fd;
    uint8_t tag[64];
    uint8_t* out;
    uint32_t outlen, toutlen;
    pufs_skcipher_init_t init;
    pufs_skcipher_update_t update;
    pufs_skcipher_final_t final;

    fd = open("/dev/pufs", O_RDWR);
    if (fd < 0) {
        printf("open /dev/pufs err!\n");
        printf("Fail!\n");
        return -1;
    }

    for (int i = 0; i < count; i++) {
        printf("case %d encrypt, pclen = %d\n", i, tp[i].ptlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_CCM;
        init.encrypt = 1;
        init.aes_ccm.keytype = KT_SWKEY;
        init.aes_ccm.keyaddr = (void*)tp[i].key;
        init.aes_ccm.keybits = tp[i].keybits;
        init.aes_ccm.nonce = (void*)tp[i].nonce;
        init.aes_ccm.noncelen = tp[i].noncelen;
        init.aes_ccm.aadlen = tp[i].aadlen;
        init.aes_ccm.inlen = tp[i].ptlen;
        init.aes_ccm.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update aad
        update.out = NULL;
        update.outlen = NULL;
        update.in = (void*)tp[i].aad;
        update.inlen = tp[i].aadlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ctlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].pt;
        update.inlen = tp[i].ptlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        final.tag = tag;
        final.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ctlen) || (memcmp(out, tp[i].ct, toutlen) != 0) || (memcmp(tag, tp[i].tag, tp[i].taglen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);

        printf("case %d decrypt, ctlen = %d\n", i, tp[i].ctlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_CCM;
        init.encrypt = 0;
        init.aes_ccm.keytype = KT_SWKEY;
        init.aes_ccm.keyaddr = (void*)tp[i].key;
        init.aes_ccm.keybits = tp[i].keybits;
        init.aes_ccm.nonce = (void*)tp[i].nonce;
        init.aes_ccm.noncelen = tp[i].noncelen;
        init.aes_ccm.aadlen = tp[i].aadlen;
        init.aes_ccm.inlen = tp[i].ctlen;
        init.aes_ccm.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update aad
        update.out = NULL;
        update.outlen = NULL;
        update.in = (void*)tp[i].aad;
        update.inlen = tp[i].aadlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ptlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].ct;
        update.inlen = tp[i].ctlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        final.tag = tag;
        final.taglen = tp[i].taglen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ptlen) || (memcmp(out, tp[i].pt, toutlen) != 0) || (memcmp(tag, tp[i].tag, tp[i].taglen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);
    }

    close(fd);

    if (ret == 0)
        printf("Success!\n");
    else
        printf("Fail!\n");

    return ret;
}

static int xts_test(const struct bc_test_pattern* tp, uint32_t count)
{
    int ret;
    int fd;
    uint8_t* out;
    uint32_t outlen, toutlen;
    pufs_skcipher_init_t init;
    pufs_skcipher_update_t update;
    pufs_skcipher_final_t final;

    fd = open("/dev/pufs", O_RDWR);
    if (fd < 0) {
        printf("open /dev/pufs err!\n");
        printf("Fail!\n");
        return -1;
    }

    for (int i = 0; i < count; i++) {
        printf("case %d encrypt, pclen = %d\n", i, tp[i].ptlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_XTS;
        init.encrypt = 1;
        init.aes_xts.keytype1 = KT_SWKEY;
        init.aes_xts.keyaddr1 = (void*)tp[i].key;
        init.aes_xts.keytype2 = KT_SWKEY;
        init.aes_xts.keyaddr2 = (void*)tp[i].key + tp[i].keybits / 8;
        init.aes_xts.keybits = tp[i].keybits;
        init.aes_xts.iv = (void*)tp[i].iv;
        init.aes_xts.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ctlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].pt;
        update.inlen = tp[i].ptlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ctlen) || (memcmp(out, tp[i].ct, toutlen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);

        printf("case %d decrypt, ctlen = %d\n", i, tp[i].ctlen);
        // init
        init.cipher = tp[i].cipher;
        init.mode = MODE_XTS;
        init.encrypt = 0;
        init.aes_xts.keytype1 = KT_SWKEY;
        init.aes_xts.keyaddr1 = (void*)tp[i].key;
        init.aes_xts.keytype2 = KT_SWKEY;
        init.aes_xts.keyaddr2 = (void*)tp[i].key + tp[i].keybits / 8;
        init.aes_xts.keybits = tp[i].keybits;
        init.aes_xts.iv = (void*)tp[i].iv;
        init.aes_xts.ivlen = tp[i].ivlen;
        ret = ioctl(fd, PUFS_SKCIPHER_INIT, &init);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_INIT err!\n");
            break;
        }
        // update
        out = malloc(tp[i].ptlen);
        update.out = out;
        update.outlen = &outlen;
        update.in = (void*)tp[i].ct;
        update.inlen = tp[i].ctlen;
        ret = ioctl(fd, PUFS_SKCIPHER_UPDATE, &update);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_UPDATE err!\n");
            break;
        }
        toutlen = outlen;
        // finish
        final.out = out + toutlen;
        final.outlen = &outlen;
        ret = ioctl(fd, PUFS_SKCIPHER_FINAL, &final);
        if (ret) {
            printf("ioctl PUFS_SKCIPHER_FINAL err!\n");
            break;
        }
        toutlen += outlen;

        ret = (toutlen != tp[i].ptlen) || (memcmp(out, tp[i].pt, toutlen) != 0);
        if (ret) {
            printf("compare err!\n");
            break;
        }
        free(out);
    }

    close(fd);

    if (ret == 0)
        printf("Success!\n");
    else
        printf("Fail!\n");

    return ret;
}

int skcipher_test(void)
{
    int ret;

    printf("##########################################################\n");
    printf("AES-ECB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_ECB, aes_ecb_tp, sizeof(aes_ecb_tp) / sizeof(aes_ecb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-CFB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CFB, aes_cfb_tp, sizeof(aes_cfb_tp) / sizeof(aes_cfb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-OFB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_OFB, aes_ofb_tp, sizeof(aes_ofb_tp) / sizeof(aes_ofb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-CBC TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CBC, aes_cbc_tp, sizeof(aes_cbc_tp) / sizeof(aes_cbc_tp[0]));
    if (ret)
        return ret;
    ret = bc_test(MODE_CBC_CS1, aes_cbc_cs1_tp, sizeof(aes_cbc_cs1_tp) / sizeof(aes_cbc_cs1_tp[0]));
    if (ret)
        return ret;
    ret = bc_test(MODE_CBC_CS2, aes_cbc_cs2_tp, sizeof(aes_cbc_cs2_tp) / sizeof(aes_cbc_cs2_tp[0]));
    if (ret)
        return ret;
    ret = bc_test(MODE_CBC_CS3, aes_cbc_cs3_tp, sizeof(aes_cbc_cs3_tp) / sizeof(aes_cbc_cs3_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-CTR TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CTR, aes_ctr_tp, sizeof(aes_ctr_tp) / sizeof(aes_ctr_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-GCM TEST DEMO\n");
    printf("##########################################################\n");
    ret = gcm_test(aes_gcm_tp, sizeof(aes_gcm_tp) / sizeof(aes_gcm_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-CCM TEST DEMO\n");
    printf("##########################################################\n");
    ret = ccm_test(aes_ccm_tp, sizeof(aes_ccm_tp) / sizeof(aes_ccm_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("AES-XTS TEST DEMO\n");
    printf("##########################################################\n");
    ret = xts_test(aes_xts_tp, sizeof(aes_xts_tp) / sizeof(aes_xts_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("SM4-ECB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_ECB, sm4_ecb_tp, sizeof(sm4_ecb_tp) / sizeof(sm4_ecb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("SM4-CFB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CFB, sm4_cfb_tp, sizeof(sm4_cfb_tp) / sizeof(sm4_cfb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("SM4-OFB TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_OFB, sm4_ofb_tp, sizeof(sm4_ofb_tp) / sizeof(sm4_ofb_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("SM4-CBC TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CBC, sm4_cbc_tp, sizeof(sm4_cbc_tp) / sizeof(sm4_cbc_tp[0]));
    if (ret)
        return ret;

    printf("##########################################################\n");
    printf("SM4-CTR TEST DEMO\n");
    printf("##########################################################\n");
    ret = bc_test(MODE_CTR, sm4_ctr_tp, sizeof(sm4_ctr_tp) / sizeof(sm4_ctr_tp[0]));
    if (ret)
        return ret;

    return 0;
}
